import type * as VueRouter from 'vue-router';
import { createRouter, createWebHistory } from 'vue-router';

import * as Enums from '@core/engine/Enums';
import { ROOT_ROUTE_NAME } from '@core/utils/router';
import Session from '@core/engine/Session';
import ThirdPlatformSession from '@core/engine/ThirdPlatform/Session';
import ReconstructionCrm from '@core/engine/ReconstructionCrm';
import EnvConfig from '@core/utils/EnvConfig';

const viewRouteModules = import.meta.glob<{ default: VueRouter.RouteRecordRaw }>(
  '../views/*/routes.*',
  { eager: true },
);
const viewRoutes = [];
for (const modulePath of Object.keys(viewRouteModules)) {
  viewRoutes.push(viewRouteModules[modulePath].default);
}

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: ROOT_ROUTE_NAME,
      redirect: '/home/index',
      children: viewRoutes,
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('@main/views/login/index.vue'),
    },
    {
      path: '/exception/403',
      name: 'exception.main.403',
      component: () => import('@core/views/exception/ErrorForbidden.vue'),
    }, {
      path: '/exception/404',
      name: 'exception.main.404',
      component: () => import('@core/views/exception/ErrorNotFound.vue'),
    }, {
      path: '/exception/503',
      name: 'exception.main.503',
      component: () => import('@core/views/exception/ErrorServiceUnavailable.vue'),
    },
    {
      path: '/:pathMatch(.*)*', redirect: '/exception/404',
    },
  ],
});

class RouteCheckError extends Error {}

router.beforeEach(async (to: VueRouter.RouteLocationNormalized, from: VueRouter.RouteLocationNormalized) => {
  try {
    checkAuth(to);
    await fetchPermission(to, from);
  } catch (error) {
    return false;
  }
});

const checkAuth = (to: VueRouter.RouteLocationNormalized): void => {
  if (EnvConfig.isConnectToPublicPlatform()) {
    return;
  }
  // 连接第三方平台时，需要检查 cookie 中缓存的 auth token，没有 token 的话跳转到登录页
  const authToken = ThirdPlatformSession.getAuthToken();
  if (to.name !== 'login' && authToken === undefined) {
    router.push({ name: 'login' });
    throw new RouteCheckError('ThirdPlatformSession.getAuthToken() returned empty');
  }
};

const fetchPermission = async (
  to: VueRouter.RouteLocationNormalized,
  from: VueRouter.RouteLocationNormalized,
): Promise<void> => {
  if (EnvConfig.isConnectTo3rdPlatform()) {
    return;
  }
  if (to.name === from.name) {
    return;
  }
  switch (to.name) {
    case Enums.ServiceTypes.LogsAudit: {
      const accountId = Session.getAccountId();
      if (!accountId) {
        throw new RouteCheckError('Session.getAccountId() returned empty');
      }
      const hasSubscribed = await ReconstructionCrm.hasAccountSubscribedService({
        serviceTag: 'CTYUN_LAS',
        resourceType: 'LAS_REG',
        accountId,
      });
      Session.setSubscribedService(Enums.ServiceTypes.LogsAudit, hasSubscribed);
      break;
    }
    default: break;
  }
};

export default router;
